
<template>
  <div>
    <ul class="zoption-ul"
        :style="{width:optionwidth,cssStyle}"
        v-if="!isdropdown">
      <li v-for="(item,Index) in commonoptionList"
          :key="Index">
        <span v-if="item.showflag && (!item.type || item.type == 'text')">
          <a @click="item.fn(record)">{{ item.title }}</a>
        </span>
        <a-popconfirm v-if="item.showflag && item.type == 'confirm' "
                      :title="item.confirm.title"
                      ok-text="确定"
                      cancel-text="取消"
                      @confirm="item.confirm.okfn(record)"
                      @cancel="item.confirm.cancelfn(record)">
          <a>{{ item.title }}</a>
        </a-popconfirm>
      </li>
    </ul>
    <ul class="zoption-ul"
        :style="{width:optionwidth,cssStyle}"
        v-else>
      <li v-for="(item,Index) in upoptionList"
          :key="Index">
        <span v-if="Index<2 && item.showflag && (!item.type || item.type == 'text')">
          <a @click="item.fn(record)">{{ item.title }}</a>
        </span>
        <a-popconfirm v-else-if=" Index<2 && item.showflag && !!item.type && item.type == 'confirm' "
                      :title="item.confirm.title"
                      ok-text="确定"
                      cancel-text="取消"
                      @confirm="item.confirm.okfn(record)"
                      @cancel="item.confirm.cancelfn(record)">
          <a>{{ item.title }}</a>
        </a-popconfirm>

        <a-dropdown v-if="Index==2"
                    placement="bottomRight">
          <template v-slot:overlay>
            <a-menu>
              <template v-for="(btnObj, cIndex) in downoptionList">
                <a-menu-item :key="cIndex">
                  <a v-if="btnObj.showflag && (!btnObj.type || btnObj.type == 'text')"
                     @click="callbackFn(btnObj)">
                    <span>{{ btnObj.title }}</span>
                  </a>
                  <a v-if="btnObj.showflag && !!btnObj.type && btnObj.type == 'confirm'"
                     @click="confirmMethod(btnObj)">
                    <span>{{ btnObj.title }}</span>
                  </a>

                </a-menu-item>
              </template>
            </a-menu>
          </template>
          <a>更多
            <a-icon type="down" />
          </a>
        </a-dropdown>
      </li>
    </ul>
  </div>
</template>
<script>
import { Menu, Modal } from 'ant-design-vue'

export default {
  name: 'Zoptionitem',
  props: {
    optiondata: {
      type: Array,
      default: null,
      require: true
    },
    cssStyle: {
      type: String,
      default: '',
      require: false
    },
    record: {
      type: Object,
      default: null,
      require: true
    }
  },

  data () {
    return {
      isdropdown: false,
      optionwidth: '100%',
      downoptionList: [],
      localoptiondata: [],
      commonoptionList: [],
      upoptionList: []
    }
  },
  methods: {
    callbackFn (item) {
      this.$nextTick(() => {
        item.fn(this.record)
      })
    },
    confirmMethod (item) {
      const that = this
      Modal.confirm({
        title: item.confirm.title,
        onOk: () => {
          that.$nextTick(() => {
            item.confirm.okfn(that.record)
          })
        },
        onCancel () { item.confirm.cancelfn(that.record) }
      })
    },
    getCondition (condition) {
      let resArr = [], res
      condition.map(con => {
        if (con.indexOf('&&') > -1 || con.indexOf('||') > -1) {
          let conditionArr = con.split(/[(&&)|(||)*]/g)
          let sign = con.match(/([(&&)|(||)])/).indexOf('|') > -1 ? '||' : '&&'
          res = this.expressConditionFunc(conditionArr[0].trim(), sign.trim(), conditionArr[2].trim())
        } else {
          res = this.expressFunc(con)
        }
        resArr.push(res)
      })
      return resArr.indexOf(false) == -1
    },
    expressConditionFunc (cond1, sign, cond2) {
      if (sign == '&&') {
        return this.expressFunc(cond1) && this.expressFunc(cond2)
      } else {
        return this.expressFunc(cond1) || this.expressFunc(cond2)
      }
    },
    expressTF (tf, key) {
      if (tf == '' || tf == '!!') {
        return this.record[key] != '' && this.record[key] != null && this.record[key] != undefined
      } else {
        return !this.record[key]
      }
    },
    expressFunc (conditionStr) {
      let signArr = conditionStr.match(/[>|<|(!=)|(=+)|(<=)|(>=)]/g)
      if (!!signArr && signArr.join().replace(/,/g, '') != '!!' && signArr.join().replace(/,/g, '') != '!') {

      } else {
        // 处理!! | ! | 这种判断
        let cArr = conditionStr.match(/([!|!{2}]*)(\w*)/)
        return this.expressTF(cArr[1], cArr[2])
      }
      let sign = signArr.join().replace(/,/g, '')
      let conditionArr = conditionStr.split(sign)
      let key = conditionArr[0].trim(), val = conditionArr[1].trim()
      if (!key || !this.record.hasOwnProperty(key.trim())) {
        throw new Error('expressFunc,【' + key + '】表达式符号错误,无法解析：' + conditionStr)
      }
      key = key.trim()
      let res
      if (sign == '<') {
        res = this.record[key] < val
      } else if (sign == '>') {
        res = this.record[key] > val
      } else if (sign == '>=') {
        res = this.record[key] >= val
      } else if (sign == '<=') {
        res = this.record[key] <= val
      } else if (sign == '!=') {
        res = this.record[key] != val
      } else if (sign == '==') {
        res = this.record[key] == val
      } else {
        throw new Error('expressFunc,【' + key + '】表达式符号错误,无法解析：' + conditionStr)
      }
      // console.warn('expressFunc' + this.record.name, 'record.' + key + sign + val, res)
      return res
    },
    validOption () {
      // 验证数据的准确性
      const that = this
      if (!that.localoptiondata || that.localoptiondata.length == 0) {
        return false
      }
      let i = 0, j = that.localoptiondata.length
      for (i; i < j; i++) {
        let item = that.localoptiondata[i]
        if (!item.title) {
          throw new Error('数据格式错误,title不能为空')
        }
        if (item.type == 'confirm' && !item.okfn) {
          throw new Error('数据格式错误,confirm okfn is undefined')
        }
      }
    },
    init () {
      let that = this
      that.localoptiondata = that.optiondata
      if (!!that.localoptiondata && that.localoptiondata.length > 0) {
        let showcount = 0, i = 0, j = that.localoptiondata.length
        for (i; i < j; i++) {
          let item = that.localoptiondata[i]
          // 初始化show 值
          if (item.show == undefined || item.show == true) item.show = true
          item.showflag = false
          let showflag
          // showcondition为空时不校验
          if (item.showcondition == undefined) {
            showflag = item.show
          } else {
            let condition = !!item.showcondition && that.getCondition(item.showcondition)
            showflag = item.show && !!item.showcondition && condition
          }
          item.showflag = showflag
          if (showflag) {
            that.commonoptionList.push(item)
            showcount++
            if (showcount >= 3) {
              that.downoptionList.push(item)
            }
            if (showcount <= 3) {
              that.upoptionList.push(item)
            }
          }
        }
        that.isdropdown = showcount > 3
      }
    }
  },
  created () {
    this.init()
    this.$watch('record', function (o, n) {
      if (o != n) {
        this.localoptiondata = []
        this.downoptionList = []
        this.commonoptionList = []
        this.upoptionList = []
        this.init()
      }
    })
  },
  mounted () {

  }
}
</script>
<style scoped lang="less">
.zoption-ul {
  -webkit-box-flex: 0;
  -ms-flex: 0 0 auto;
  flex: 0 0 auto;
  padding: 0;
  font-size: 0;
  list-style: none;
  li {
    position: relative;
    display: inline-block;
    padding: 0 8px;
    color: rgba(0, 0, 0, 0.45);
    font-size: var(--font-size-def);
    line-height: 14px;
    text-align: center;
    cursor: pointer;
    border-right: 1px solid #e8e8e8;
  }
  li:last-child {
    border-right: none;
  }
}
</style>